package email

import (
	"crypto/tls"
	"fmt"
	"github.com/rs/zerolog/log"
	"net/smtp"
	"strings"
)

// EmailService 邮件服务结构体
type EmailService struct {
	SMTPHost  string
	SMTPPort  int
	Username  string
	Password  string
	FromName  string
	EnableTLS bool
}

// EmailTemplate 邮件模板结构体
type EmailTemplate struct {
	Subject string
	Body    string
	IsHTML  bool
}


//EmailConfig ...
type EmailConfig struct {
	SMTPHost  string `json:"smtp_host"`
	SMTPPort  int    `json:"smtp_port"`
	Username  string `json:"username"`
	Password  string `json:"password"`
	FromName  string `json:"from_name"`
	EnableTLS bool   `json:"enable_tls"`
}

type Opts func(*EmailService)

func WithEnableTLS(tls bool) Opts {
	return func(c *EmailService) {
		c.EnableTLS = tls
	}
}

func WithFromName(fName string) Opts {
	return func(c *EmailService) {
		c.FromName = fName
	}
}

func WithPassword(pwd string) Opts {
	return func(c *EmailService) {
		c.Password = pwd
	}
}

func WithUserName(name string) Opts {
	return func(c *EmailService) {
		c.Username = name
	}
}

func WithSmtpPort(port int) Opts {
	return func(c *EmailService) {
		c.SMTPPort = port
	}
}

func WithSmtpHost(host string) Opts {
	return func(c *EmailService) {
		c.SMTPHost = host
	}
}
// NewEmailService 创建邮件服务实例
func NewEmailService(opts ...Opts) *EmailService {
	service := &EmailService{}
	for _, opt := range opts {
		opt(service)
	}
	return service
}

// SendEmail 发送邮件
func (e *EmailService) SendEmail(to []string, subject, body string, isHTML bool) error {
	if e == nil {
		return fmt.Errorf("邮件服务未初始化")
	}

	// 创建SMTP客户端
	client := NewSMTPClient(e.SMTPHost, e.SMTPPort, e.Username, e.Password)

	// 发送邮件
	if err := client.SendMail(e.Username, e.FromName, to, subject, body, isHTML); err != nil {
		log.Err(err).Msg("邮件发送失败")
		return fmt.Errorf("邮件发送失败: %v", err)
	}

	log.Info().Strs("recipients", to).Str("subject", subject).Msg("邮件发送成功")
	return nil
}

// SendEmailWithCC 发送带抄送的邮件
func (e *EmailService) SendEmailWithCC(to, cc []string, subject, body string, isHTML bool) error {
	if e == nil {
		return fmt.Errorf("邮件服务未初始化")
	}

	// 合并收件人和抄送
	allRecipients := append(to, cc...)

	// 构建带抄送的邮件头
	headers := make(map[string]string)
	headers["From"] = fmt.Sprintf("%s <%s>", e.FromName, e.Username)
	headers["To"] = strings.Join(to, ",")
	if len(cc) > 0 {
		headers["Cc"] = strings.Join(cc, ",")
	}
	headers["Subject"] = subject
	headers["MIME-Version"] = "1.0"

	if isHTML {
		headers["Content-Type"] = "text/html; charset=UTF-8"
	} else {
		headers["Content-Type"] = "text/plain; charset=UTF-8"
	}

	// 构建邮件内容
	message := ""
	for k, v := range headers {
		message += fmt.Sprintf("%s: %s\r\n", k, v)
	}
	message += "\r\n" + body

	// 发送邮件
	addr := fmt.Sprintf("%s:%d", e.SMTPHost, e.SMTPPort)
	auth := smtp.PlainAuth("", e.Username, e.Password, e.SMTPHost)

	var err error
	if e.EnableTLS && (e.SMTPPort == 465 || e.SMTPPort == 587) {
		// 使用TLS连接
		tlsConfig := &tls.Config{
			InsecureSkipVerify: true,
			ServerName:         e.SMTPHost,
		}

		conn, dialErr := tls.Dial("tcp", addr, tlsConfig)
		if dialErr != nil {
			return dialErr
		}
		defer conn.Close()

		smtpClient, clientErr := smtp.NewClient(conn, e.SMTPHost)
		if clientErr != nil {
			return clientErr
		}
		defer smtpClient.Quit()

		if err = smtpClient.Auth(auth); err != nil {
			return err
		}

		if err = smtpClient.Mail(e.Username); err != nil {
			return err
		}

		for _, addr := range allRecipients {
			if err = smtpClient.Rcpt(addr); err != nil {
				return err
			}
		}

		w, err := smtpClient.Data()
		if err != nil {
			return err
		}

		_, err = w.Write([]byte(message))
		if err != nil {
			return err
		}

		err = w.Close()
	} else {
		err = smtp.SendMail(addr, auth, e.Username, allRecipients, []byte(message))
	}

	if err != nil {
		log.Error().Err(err).Msg("邮件发送失败")
		return fmt.Errorf("邮件发送失败: %v", err)
	}

	log.Info().Strs("recipients", allRecipients).Str("subject", subject).Msg("邮件发送成功")
	return nil
}

// SendTemplateEmail 发送模板邮件
func (e *EmailService) SendTemplateEmail(to []string, template *EmailTemplate, variables map[string]string) error {
	subject := template.Subject
	body := template.Body

	// 替换模板变量
	for key, value := range variables {
		placeholder := fmt.Sprintf("{{%s}}", key)
		subject = strings.ReplaceAll(subject, placeholder, value)
		body = strings.ReplaceAll(body, placeholder, value)
	}

	return e.SendEmail(to, subject, body, template.IsHTML)
}

// GetWelcomeTemplate 获取欢迎邮件模板
func GetWelcomeTemplate() *EmailTemplate {
	return &EmailTemplate{
		Subject: "欢迎加入{{system_name}}",
		Body: `<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>欢迎邮件</title>
</head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
    <div style="max-width: 600px; margin: 0 auto; padding: 20px;">
        <h2 style="color: #2c3e50;">欢迎加入{{system_name}}！</h2>
        <p>亲爱的 {{username}}，</p>
        <p>欢迎您成为我们系统的一员！您的账户已经成功创建。</p>
        <div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
            <h3 style="margin-top: 0;">账户信息：</h3>
            <p><strong>用户名：</strong>{{username}}</p>
            <p><strong>邮箱：</strong>{{email}}</p>
            <p><strong>注册时间：</strong>{{register_time}}</p>
        </div>
        <p>如果您有任何问题，请随时联系我们的客服团队。</p>
        <p>祝您使用愉快！</p>
        <hr style="border: none; border-top: 1px solid #eee; margin: 30px 0;">
        <p style="font-size: 12px; color: #666;">
            此邮件由系统自动发送，请勿回复。<br>
            {{system_name}} 团队
        </p>
    </div>
</body>
</html>`,
		IsHTML: true,
	}
}

// GetPasswordResetTemplate 获取密码重置邮件模板
func GetPasswordResetTemplate() *EmailTemplate {
	return &EmailTemplate{
		Subject: "{{system_name}} - 密码重置请求",
		Body: `<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>密码重置</title>
</head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
    <div style="max-width: 600px; margin: 0 auto; padding: 20px;">
        <h2 style="color: #e74c3c;">密码重置请求</h2>
        <p>亲爱的 {{username}}，</p>
        <p>我们收到了您的密码重置请求。请点击下面的链接重置您的密码：</p>
        <div style="text-align: center; margin: 30px 0;">
            <a href="{{reset_link}}" 
               style="background-color: #3498db; color: white; padding: 12px 30px; 
                      text-decoration: none; border-radius: 5px; display: inline-block;">
                重置密码
            </a>
        </div>
        <p><strong>注意：</strong>此链接将在 {{expire_time}} 小时后失效。</p>
        <p>如果您没有请求重置密码，请忽略此邮件。</p>
        <p>为了您的账户安全，请不要将此链接分享给他人。</p>
        <hr style="border: none; border-top: 1px solid #eee; margin: 30px 0;">
        <p style="font-size: 12px; color: #666;">
            此邮件由系统自动发送，请勿回复。<br>
            {{system_name}} 团队
        </p>
    </div>
</body>
</html>`,
		IsHTML: true,
	}
}

// GetNotificationTemplate 获取通知邮件模板
func GetNotificationTemplate() *EmailTemplate {
	return &EmailTemplate{
		Subject: "{{system_name}} - {{notification_type}}",
		Body: `<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>系统通知</title>
</head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
    <div style="max-width: 600px; margin: 0 auto; padding: 20px;">
        <h2 style="color: #2c3e50;">{{notification_type}}</h2>
        <p>亲爱的 {{username}}，</p>
        <div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
            {{content}}
        </div>
        <p>时间：{{timestamp}}</p>
        <p>如有疑问，请联系系统管理员。</p>
        <hr style="border: none; border-top: 1px solid #eee; margin: 30px 0;">
        <p style="font-size: 12px; color: #666;">
            此邮件由系统自动发送，请勿回复。<br>
            {{system_name}} 团队
        </p>
    </div>
</body>
</html>`,
		IsHTML: true,
	}
}
